package tencent

import (
	"context"
	"fmt"
	"gitee.com/bobo-rs/creative-framework/enums"
	"gitee.com/bobo-rs/creative-framework/pkg/sms/models"
	"gitee.com/bobo-rs/creative-framework/pkg/utils"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	tencentSms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms/v20210111"
)

// Ctx 设置上下文
func (h *Handler) Ctx(ctx context.Context) {
	h.ctx = ctx
}

// Config 设置TencentSDK配置
func (h *Handler) Config(config interface{}) error {

	// 配置不存在
	if err := gconv.Struct(config, &h.config); err != nil {
		return fmt.Errorf(`tencent config failed %w`, err)
	}
	// 签名
	h.config.SmsTencentSignMethod = SmsSignMethod
	// 默认区域设置
	if len(h.config.SmsTencentRegion) == 0 {
		h.config.SmsTencentRegion = SmsRegion
	}
	// 区号
	if len(h.config.CountryCode) == 0 {
		h.config.CountryCode = enums.CountryCodeChina
	}
	return nil
}

// Send 发送短信
func (h *Handler) Send(mobile []string, in models.SendSmsInput) (resp *models.SendSmsResponse, err error) {

	// 实例化要请求产品(以sms为例)的client对象
	client, err := tencentSms.NewClient(
		h.credential(), h.config.SmsTencentRegion, h.clientProfile(),
	)
	if err != nil {
		return nil, fmt.Errorf(`tencent new client failed %w`, err)
	}

	// 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
	req := tencentSms.NewSendSmsRequest()
	req.SmsSdkAppId = common.StringPtr(h.config.SmsTencentSdkAppid)
	req.TemplateId = common.StringPtr(in.TemplateId)

	// 填充手机号
	req.PhoneNumberSet = common.StringPtrs(utils.SliceAddPrefix(mobile, string(h.config.CountryCode)))

	// 国内短信无需填写该项；国际/港澳台短信已申请独立 SenderId 需要填写该字段，默认使用公共 SenderId，无需填写该字段
	if h.config.CountryCode != enums.CountryCodeChina {
		req.SenderId = common.StringPtr(h.config.SmsTencentSenderId)
	}

	// 模板参数
	req.TemplateParamSet = common.StringPtrs(in.TemplateParams)

	// 请求接口，发送短信
	response, err := client.SendSms(req)

	// 处理异常
	if err = h.commonErrorHandler(err); err != nil {
		return nil, fmt.Errorf(`tencent an API error has returned: %s`, err)
	}

	// 初始化响应结果
	resp = &models.SendSmsResponse{
		RequestId: *response.Response.RequestId,
		Results:   h.sendStatusSetResponse(response.Response.SendStatusSet),
	}
	return
}

// Pull 拉取发送短信结果
func (h *Handler) Pull(in models.PullSendStatusInput) (resp []*models.PullSendResultItem, err error) {

	// 实例客户端
	client, err := tencentSms.NewClient(
		h.credential(), h.config.SmsTencentRegion, h.clientProfile(),
	)
	if err != nil {
		return nil, fmt.Errorf(`tencent new client pull failed %w`, err)
	}

	var statusSet []*tencentSms.PullSmsSendStatus
	// 选择单一还是全部
	switch len(in.Mobile) {
	case 0:
		// 全部
		statusSet, err = h.pullSendStatusHandler(in.Limit, client)
	default:
		// 单一手机号
		statusSet, err = h.pullSendStatusByPhoneNumberHandler(in, client)
	}
	if err != nil {
		return nil, err
	}

	return h.pullSmsSendStatusSetResponse(statusSet), nil
}

// Apply 申请或修改短信模板-审核通过不允许修改
func (h *Handler) Apply(in models.AddSmsTemplateInput) (resp *models.AddSmsTemplateResponse, err error) {

	// 实例客户端
	client, err := tencentSms.NewClient(
		h.credential(), h.config.SmsTencentRegion, h.clientProfile(),
	)
	if err != nil {
		return nil, fmt.Errorf(`tencent new client apply failed %w`, err)
	}

	resp = &models.AddSmsTemplateResponse{}
	// 添加或修改短信模板
	switch len(in.TemplateId) {
	case 0:
		// 添加
		resp.TemplateId, err = h.addSmsTemplateHandler(in, client)
	default:
		// 修改
		resp.TemplateId, err = h.modifySmsTemplateHandler(in, client)
	}

	return
}

// List 获取短信模板列表
func (h *Handler) List(in models.SmsTemplateListInput) (resp *models.SmsListResponse, err error) {

	// 实例客户端
	client, err := tencentSms.NewClient(
		h.credential(), h.config.SmsTencentRegion, h.clientProfile(),
	)
	if err != nil {
		return nil, fmt.Errorf(`tencent new client apply failed %w`, err)
	}

	return h.describeSmsTemplateListHandler(in, client)
}
